const path = require('path');
const fs = require('fs');
const webpack = require('webpack');
const { defineConfig } = require('@vue/cli-service');

/**
 * 支持按环境变量 VUE_APP_CURRENT_APP 构建单个页面目录（比如 src/views/1）
 * - 非选中目录下的模块会被替换为项目根的 empty.js，从而避免被打包
 * - 同时限制 vue-loader 只处理选中目录下的 .vue 文件以加快构建
 *
 * 用法（PowerShell）:
 *   $env:VUE_APP_CURRENT_APP='1'; npm run build
 */
module.exports = defineConfig({
  publicPath: './',
  transpileDependencies: true,

  chainWebpack: (config) => {
    const appName = process.env.VUE_APP_CURRENT_APP;
    if (appName) {
      // 限制只处理当前应用的 Vue 文件（避免对未选中页面做 loader 处理）
      // 保留对 src/App.vue 的处理（主入口）
      config.module
        .rule('vue')
        .include
        .add(path.resolve(__dirname, 'src/views', appName))
        .add(path.resolve(__dirname, 'src/App.vue'))
        .end();
    }
  },

  configureWebpack: (config) => {
    const appName = process.env.VUE_APP_CURRENT_APP;
    if (appName) {
      // 为了更可靠地排除未选中的 views 文件夹，显式为每个非目标目录添加 IgnorePlugin
      // 列出 src/views 下的所有子目录（在开发环境中我们已通过 fs 或手动查看得到 '1' 和 '2'）
      const subDirs = fs.readdirSync(path.resolve(__dirname, 'src', 'views'));

      const ignorePlugins = subDirs
        .filter((d) => d !== appName)
        .map((d) => {
          // 忽略该目录下所有文件的上下文导入
          // 当 webpack 试图解析来自该目录的相对导入时会被忽略，从而不会把这些模块包含到 bundle
          return new webpack.IgnorePlugin({
            resourceRegExp: new RegExp('^\\./.*$'),
            contextRegExp: new RegExp(`${path.posix.join('src', 'views', d)}$`)
          });
        });

      // 根据 resource.request 和 resource.context 同时匹配路径，拦截显式的 '@/views/2/...' 或 'src/views/2/...' 请求
      const fallbackReplace = new webpack.NormalModuleReplacementPlugin(/./, (resource) => {
        try {
          const ctx = resource.context || '';
          const req = resource.request || '';

          const normalizedCtx = ctx.split(path.sep).join('/');
          const normalizedReq = req.split(path.sep).join('/');

          // 支持两种路径形式：@/views/... 和 src/views/...
          const aliasPrefix = '@/views';
          const viewsPrefix = path.posix.join('src', 'views');
          const targetAliases = [path.posix.join(aliasPrefix, appName), path.posix.join(viewsPrefix, appName)];

          const reqMatchesViews = normalizedReq.includes(aliasPrefix) || normalizedReq.includes(viewsPrefix);
          const ctxMatchesViews = normalizedCtx.includes(viewsPrefix);

          const reqIsTarget = targetAliases.some((tp) => normalizedReq.includes(tp));
          const ctxIsTarget = targetAliases.some((tp) => normalizedCtx.includes(tp));

          const isOutsideTarget = (reqMatchesViews && !reqIsTarget) || (ctxMatchesViews && !ctxIsTarget);

          if (isOutsideTarget) {
            resource.request = path.resolve(__dirname, 'empty.js');
          }
        } catch (e) {}
      });

      // 可选：把当前应用单独作为一个 chunk，减小其他 chunk 的引用
      const splitConfig = {
        splitChunks: {
          cacheGroups: {
            app: {
              test: new RegExp(`src[\\\\/]views[\\\\/]${appName}`),
              name: `app-${appName}`,
              chunks: 'all'
            }
          }
        }
      };

      return {
        plugins: [...ignorePlugins, fallbackReplace],
        optimization: splitConfig
      };
    }
  },

  productionSourceMap: false
});
